package com.probox.common.core.utils.bean;

import com.alibaba.fastjson.JSONObject;
import com.probox.common.core.annotation.NotEmpty;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CheckBeanUtils {

    private static final String EMPTY="不能为空";
    private static final String RANGE="参数不符合要求";
    /**
     * 根据注解判断值为空 把对象转json然后判断 被标注的实体类上的字段有没有传值或者值是不是为空 以及符不符合字段范围要求
     * @param tar
     * @param <T>
     */
    public static <T,R> R checkBean(T tar, Class<R> resultType, String type) throws Exception {
        String res= JSONObject.toJSONString(tar);
        JSONObject json = JSONObject.parseObject(res);
        //这里用json的原因是 属性如果是基本类型不穿就是默认值 比如 int是0 用json的话就是空字符串
        //String[] split = res.replace("{","").replace("}","").split(",");
        Field[] fields = tar.getClass().getDeclaredFields();
        String primaryNode=null;
        for(int i=0;i<fields.length;i++)
            if (fields[i].getAnnotation(NotEmpty.class) != null) {
                if (fields[i].getAnnotation(NotEmpty.class).type().equals(type)) {
                    if (fields[i].getAnnotation(NotEmpty.class).primary()) {
                        if (findString(json, fields[i].getName()) == -1)
                            throw new Exception(fields[i].getAnnotation(NotEmpty.class).value() + EMPTY);
                        fields[i].setAccessible(true);
                        primaryNode = (String) fields[i].get(tar);
                        NotEmpty annotation = fields[i].getAnnotation(NotEmpty.class);
                        List<String> notEmpties = new ArrayList<String>(Arrays.asList(annotation.range()));
                        Field field = fields[i];
                        if (!CollectionUtils.isEmpty(notEmpties)) {
                            fields[i].setAccessible(true);
                            String o = (String) field.get(tar);
                            if (!notEmpties.contains(o))
                                throw new Exception(annotation.value() + RANGE);
                        }
                        continue;
                    }
                    if (!fields[i].getAnnotation(NotEmpty.class).dependsOn().equals("")) {
                        if (fields[i].getAnnotation(NotEmpty.class).dependsOn().equals(primaryNode)) {
                            if (findString(json, fields[i].getName()) == -1)
                                throw new Exception(fields[i].getAnnotation(NotEmpty.class).value());
                            else
                                continue;
                        } else {
                            continue;
                        }
                    }
                    if (findString(json, fields[i].getName()) == -1)
                        throw new Exception(fields[i].getAnnotation(NotEmpty.class).value());
                    NotEmpty annotation = fields[i].getAnnotation(NotEmpty.class);
                    List<String> notEmpties = new ArrayList<String>(Arrays.asList(annotation.range()));
                    Field field = fields[i];
                    if (!CollectionUtils.isEmpty(notEmpties)) {
                        fields[i].setAccessible(true);
                        String o = (String) field.get(tar);
                        if (!notEmpties.contains(o))
                            throw new Exception(annotation.value() + RANGE);
                    }

                }
            }
        R result=resultType.newInstance();
        //先找到tar 然后找他不为空的属性 然后创建一个
        Field[] declaredFields = tar.getClass().getDeclaredFields();
        for(int i=0;i<declaredFields.length;i++){
            fields[i].setAccessible(true);
            fields[i].get(tar);
            Method set = resultType.getMethod(new StringBuffer("set").append(toUpperCase(fields[i].getName())).toString(),fields[i].getType());
            set.setAccessible(true);
            set.invoke(result,fields[i].get(tar));
        }
        return result;

    }



    public <T,R> R toBean(T target,R result){
        return null;
    }


    public static String toUpperCase(String name){
        char[] chars = name.toCharArray();
        chars[0]=(char)(chars[0]-32);
        return new String(chars);
    }

    /**
     *稀疏数组查找一个tar
     * @param json
     * @param s
     * @return
     */
    public static int findString(JSONObject json, String s) {
    	int rst = 0;
    	if (!json.containsKey(s)) {
    		return -1;
    	}
    	if (json.get(s) == null) {
    		return -1;
    	}
    	return rst;
    	/*
        int n = words.length;
        int left = 0;
        int right = n - 1;
        while (left <= right) {
            int mid = (left + right)/2;
            while(mid <= right && "".equals(words[mid])) {
                mid++;
            }
            if (mid > right) {
                mid = (left + right)/2 - 1;
                while (mid >= left && "".equals(words[mid])) {
                    mid--;
                }
                if (mid < left) {
                    return -1;
                }
            }
            int temp = s.compareTo(words[mid].split(":")[0]);
            if (temp == 0) {
                String res=words[mid].split(":")[1];
                if(res==null||res.equals("\"\""))
                    return -1;
                return mid;
            }
            if (temp > 0) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
        */
    }




//        public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
////        MemberInoviceQuery query=new MemberInoviceQuery();
////        query.setInvoiceTitle("person");
////        query.setCompanyNo("2321");
////        //query.setCompanyPhone();
////        MemberInvoice memberInvoice = (MemberInvoice)checkBean(query,MemberInvoice.class, NotEmpty.SAVE_TYPE_SAVE);
//
//
//            PayOrderProofQuery query=new PayOrderProofQuery();
//            query.setOrderNo("321312");
//            query.setProofMoney(21321L);
//            PayOrderProof memberInvoice = (PayOrderProof)checkBean(query,PayOrderProof.class, NotEmpty.SAVE_TYPE_SAVE);
//    }

}
